﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NetworkingLibrary.Clients.TCP;
using NetworkingLibrary.Servers.TCP.Java;
using NetworkingLibrary.Messages;
using NetworkingLibrary.Messages.Specialised.Game;
using NetworkingLibrary.Events;
using NetworkingLibrary.Exceptions;

using System.Net;
using System.Threading;

namespace TCP_Test_Application
{
    class Program
    {
        const int LoopDelay = 150;
        static int ServerPort = 25571;
        
        static Random Rand = new Random();

        static IPAddress LocalMachineAddress = Dns.GetHostAddresses(Dns.GetHostName()).First();

        static JavaTCPServer TheTCPServer;
            
        static void Main(string[] args)
        {
            TheTCPServer = new JavaTCPServer();
            TheTCPServer.OnClientConnect += new ClientConnectDelegate(TheTCPServer_OnClientConnect);
            TheTCPServer.OnClientDisconnect += new ClientDisconnectDelegate(TheTCPServer_OnClientDisconnect);
            TheTCPServer.OnError += new ErrorDelegate(TheTCPServer_OnError);
            TheTCPServer.OnMaxConnections += new MaxConnectionsDelegate(TheTCPServer_OnMaxConnections);
            TheTCPServer.OnMessageReceived += new MessageReceivedDelegate(TheTCPServer_OnMessageReceived);

            if (TheTCPServer.Start(ServerPort, null))
            {
                Console.WriteLine("TCP server started.");
                Console.ReadLine();

                //TCPClient TCPClient1 = new TCPClient();
                //TCPClient1.OnConnect += new ClientConnectDelegate(TCPClient1_OnConnect);
                //TCPClient1.OnDisconnect += new ClientDisconnectDelegate(TCPClient1_OnDisconnect);
                //TCPClient1.OnError += new ErrorDelegate(TCPClient1_OnError);
                //TCPClient1.OnMessageReceived += new MessageReceivedDelegate(TCPClient1_OnMessageReceived);

                //if (TCPClient1.Connect(ServerPort, LocalMachineAddress))
                //{
                //    TCPClient1.FlowControl = true;

                //    TCPClient TCPClient2 = new TCPClient();
                //    TCPClient2.OnConnect += new ClientConnectDelegate(TCPClient2_OnConnect);
                //    TCPClient2.OnDisconnect += new ClientDisconnectDelegate(TCPClient2_OnDisconnect);
                //    TCPClient2.OnError += new ErrorDelegate(TCPClient2_OnError);
                //    TCPClient2.OnMessageReceived += new MessageReceivedDelegate(TCPClient2_OnMessageReceived);

                //    if (TCPClient2.Connect(ServerPort, LocalMachineAddress))
                //    {
                //        TCPClient2.FlowControl = true;

                //        bool Terminate = false;
                //        while (!Terminate)
                //        {
                //            Console.WriteLine();
                //            Console.WriteLine();
                //            Console.WriteLine("-----------------------------------------");
                //            Console.WriteLine();
                //            Console.WriteLine("Press enter to send test message or escape to exit.");
                //            ConsoleKeyInfo Input = Console.ReadKey();
                //            if (Input.Key == ConsoleKey.Enter)
                //            {
                //                TestMessage AMessage = new TestMessage(new Random().Next(), "Your random number is : ");
                //                //Thread.Sleep(100) required otherwise the Random returns exact same number twice.
                //                Thread.Sleep(100);
                //                TestMessage BMessage = new TestMessage(new Random().Next(), "Your random number is : ");
                                
                //                TCPClient1.Send(AMessage);
                //                TCPClient2.Send(BMessage);

                //                Thread.Sleep(LoopDelay);
                //            }
                //            else if (Input.Key == ConsoleKey.Escape)
                //            {
                //                Terminate = true;
                //            }
                //        }

                //        if (!TCPClient2.Disconnect())
                //        {
                //            Console.WriteLine("Failed to disconnect TCPClient2!");
                //        }
                //    }

                //    if (!TCPClient1.Disconnect())
                //    {
                //        Console.WriteLine("Failed to disconnect TCPClient1!");
                //    }
                //}
                //else
                //{
                //    Console.WriteLine("Failed to connect TCPClient1!");
                //}

                if (!TheTCPServer.Stop())
                {
                    Console.WriteLine("Failed to stop TCP server!");
                }
            }
            else
            {
                Console.WriteLine("Failed to start TCP server!");
            }

            Console.WriteLine("---------------------------");
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }

        static void TheTCPServer_OnMessageReceived(MessageReceivedEventArgs e)
        {
            Type MessageType = e.TheMessage.GetType();
            if (MessageType == typeof(TestMessage))
            {
                TestMessage TheMessage = (TestMessage)e.TheMessage;
                Console.WriteLine("TCP server message receieved : " + MessageType.Name + " : ");
                Console.WriteLine(TheMessage.StringTest + " : " + TheMessage.NumberTest);
            }
            else if (MessageType == typeof(NetworkingLibrary.Messages.Java.JavaMessageObject))
            {
                foreach (KeyValuePair<string, NetworkingLibrary.Messages.Java.JavaDataObject> AnObj in ((NetworkingLibrary.Messages.Java.JavaMessageObject)e.TheMessage).AllObjects)
                {
                    Console.WriteLine(AnObj.Key + " : " + AnObj.Value.ToString());
                }
                foreach (NetworkingLibrary.Clients.IClient AClient in TheTCPServer.AllClients.Values)
                {
                    if (AClient.ID != e.TheClient.ID)
                    {                        
                        AClient.Send(e.TheMessage);
                    }
                }
            }
        }
        static void TheTCPServer_OnMaxConnections(MaxConnectionsEventArgs e)
        {
            Console.WriteLine("TCP Server max connections reached.");
        }
        static void TheTCPServer_OnError(ErrorEventArgs e)
        {
            Console.Write(e.TheException.Message);
        }
        static void TheTCPServer_OnClientDisconnect(ClientDisconnectEventArgs e)
        {
            Console.WriteLine("TCP Server client disconnected.");
        }
        static void TheTCPServer_OnClientConnect(ClientConnectEventArgs e)
        {
            Console.WriteLine("TCP Server client connected.");
        }

        static void TCPClient1_OnError(ErrorEventArgs e)
        {
            Console.Write(e.TheException.Message);
        }
        static void TCPClient1_OnDisconnect(ClientDisconnectEventArgs e)
        {
            Console.WriteLine("TCP Client 1 disconnected.");
        }
        static void TCPClient1_OnConnect(ClientConnectEventArgs e)
        {
            Console.WriteLine("TCP Client 1 connected.");
        }
        static void TCPClient1_OnMessageReceived(MessageReceivedEventArgs e)
        {
            Type MessageType = e.TheMessage.GetType();
            if (MessageType == typeof(TestMessage))
            {
                TestMessage TheMessage = (TestMessage)e.TheMessage;
                Console.WriteLine("TCP Client 1 message receieved : " + MessageType.Name + " : ");
                Console.WriteLine(TheMessage.StringTest + " : " + TheMessage.NumberTest);
            }
        }

        static void TCPClient2_OnError(ErrorEventArgs e)
        {
            Console.Write(e.TheException.Message);
        }
        static void TCPClient2_OnDisconnect(ClientDisconnectEventArgs e)
        {
            Console.WriteLine("TCP Client 2 disconnected.");
        }
        static void TCPClient2_OnConnect(ClientConnectEventArgs e)
        {
            Console.WriteLine("TCP Client 2 connected.");
        }
        static void TCPClient2_OnMessageReceived(MessageReceivedEventArgs e)
        {
            Type MessageType = e.TheMessage.GetType();
            if (MessageType == typeof(TestMessage))
            {
                TestMessage TheMessage = (TestMessage)e.TheMessage;
                Console.WriteLine("TCP Client 2 message receieved : " + MessageType.Name + " : ");
                Console.WriteLine(TheMessage.StringTest + " : " + TheMessage.NumberTest);
            }
        }
        
    }
}
